﻿using NAudio.Wave.SampleProviders;
using NAudio.Wave;
using System.Text.RegularExpressions;

namespace SenseVoiceSharp
{
    public static class SenseVoiceHelpers
    {
        public static byte[] ConvertFloatToByte(float[] floatBuffer)
        {
            var byteBuffer = new byte[floatBuffer.Length * 4];
            Buffer.BlockCopy(floatBuffer, 0, byteBuffer, 0, byteBuffer.Length);
            return byteBuffer;
        }

        public static (float[] Samples, int SampleRate, int channels) ReadWav(string filePath)
        {
            using var reader = new WaveFileReader(filePath);
            var bytes = new byte[reader.Length];
            reader.Read(bytes, 0, bytes.Length);
            float[] samples;
            int sampleRate = reader.WaveFormat.SampleRate;
            var channels = reader.WaveFormat.Channels;
            if (reader.WaveFormat.BitsPerSample == 16)
            {
                samples = new float[bytes.Length / 2];
                for (int i = 0; i < samples.Length; i++)
                {
                    short int16 = BitConverter.ToInt16(bytes, i * 2);
                    samples[i] = int16 / 32768f;
                }
            }
            else if (reader.WaveFormat.BitsPerSample == 32 && reader.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat)
            {
                samples = new float[bytes.Length / 4];
                Buffer.BlockCopy(bytes, 0, samples, 0, bytes.Length);
            }
            else
            {
                throw new NotSupportedException("Unsupported WAV format.");
            }
            return (samples, sampleRate, channels);
        }

        public static float[] ResampleAudio(float[] originalSamples, int originalSampleRate, int targetSampleRate, int channels = 1)
        {
            var originalFormat = WaveFormat.CreateIeeeFloatWaveFormat(originalSampleRate, channels);
            var provider = new RawSourceWaveStream(
                new MemoryStream(SenseVoiceHelpers.ConvertFloatToByte(originalSamples)),
                originalFormat
            ).ToSampleProvider();
            var resampler = new WdlResamplingSampleProvider(provider, targetSampleRate);
            var targetLength = (int)(originalSamples.Length * (double)targetSampleRate / originalSampleRate);
            var resampled = new float[targetLength];
            int samplesRead = resampler.Read(resampled, 0, resampled.Length);
            return resampled.Take(samplesRead).ToArray();
        }

        public static string ResRe(string result)
        {
            var pattern = @"<\|([^|]+)\|>";
            var text = Regex.Replace(result, pattern, "").Trim();
            return text;
        }
    }
}